<?php

namespace Payment\Query\Wx;

use Exception;
use Payment\Common\PayException;
use Payment\Common\Weixin\Data\Query\PayBankQueryData;
use Payment\Common\Weixin\WxBaseStrategy;
use Payment\Common\WxConfig;
use Payment\Config;
use Payment\Utils\Curl;
use Payment\Utils\DataParser;

/**
 * 微信企业付款到银行卡查询
 * Class WxPayBankQuery
 * @package Payment\Query
 */
class WxPayBankQuery extends WxBaseStrategy
{

    public function getBuildDataClass()
    {
        return PayBankQueryData::class;
    }

    /**
     * 使用证书方式进行查询
     * @param string $xml
     * @param string $url
     * @return array
     *
     */
    protected function curlPost($xml, $url)
    {
        $curl = new Curl();
        $responseTxt = $curl->set([
            'CURLOPT_HEADER' => 0,
            'CURLOPT_SSL_VERIFYHOST' => false,
            'CURLOPT_SSLCERTTYPE' => 'PEM', //默认支持的证书的类型，可以注释
            'CURLOPT_SSLCERT' => $this->config->appCertPem,
            'CURLOPT_SSLKEY' => $this->config->appKeyPem,
            'CURLOPT_CAINFO' => $this->config->cacertPath,
        ])->post($xml)->submit($url);

        return $responseTxt;
    }

    /**
     * 返回付款查询url
     * @return string
     *
     */
    protected function getReqUrl()
    {
        return WxConfig::PAY_BANK_QUERY_URL;
    }

    /**
     * 处理微信的返回值并返回给客户端
     * @param array $data
     * @return array|mixed
     * @createTime 2019/10/10 14:59
     */
    protected function retData(array $data)
    {
        if ($this->config->returnRaw) {
            $data['channel'] = Config::WX_PAY_BANK;
            return $data;
        }

        //请求失败，可能是网络原因
        if ($data['return_code'] != 'SUCCESS') {
            return $retData = [
                'is_success' => 'F',
                'error' => $data['return_msg'],
                'channel' => Config::WX_PAY_BANK,
            ];
        }

        //业务失败
        if ($data['result_code'] != 'SUCCESS') {
            return $retData = [
                'is_success' => 'F',
                'error_code' => $ret['err_code'] ?? '',
                'error' => $data['err_code_des'] ?? '',
                'channel' => Config::WX_PAY_BANK,
            ];
        }

        //正确
        return $this->createBackData($data);
    }

    /**
     * 处理微信的返回值并返回给客户端
     * @param array $data
     * @return array
     * @createTime 2019/10/10 14:58
     */
    protected function createBackData(array $data)
    {
        $retData = [
            'is_success' => 'T',
            'response' => [
                'trans_no' => $data['partner_trade_no'], //商户企业付款单号
                'transaction_id' => $data['payment_no'], //微信企业付款单号（代付成功后，返回的内部业务单号）
                'amount' => bcdiv($data['amount'], 100, 2), //代付金额，单位：分。为了保持一致性，故此转为元
                'fee' => bcdiv($data['cmms_amt'], 100, 2), //手续费金额，单位：分。为了保持一致性，故此转为元
                'status' => strtolower($data['status']),//代付单状态
                'reason' => $data['reason'], //失败原因
                'payer_bank_no_md5' => $data['bank_no_md5'], //收款用户银行卡号（MD5加密）
                'payer_real_name_md5' => $data['true_name_md5'], //收款人真实姓名（MD5加密）
                'create_date' => $data['create_time'] ?? '', //微信企业付款订单创建时间
                'pay_success_date' => $data['pay_succ_time'] ?? '', //微信企业付款到银行卡付款成功时间（依赖银行的处理进度，可能出现延迟返回，甚至被银行退票的情况）
                'desc' => $data['desc'] ?? '', //付款描述
                'channel' => Config::WX_PAY_BANK,
            ],
        ];

        return $retData;
    }

    /**
     * @param array $data
     *
     * @return array|string
     * @throws PayException
     * @throws Exception
     */
    public function handle(array $data)
    {
        $buildClass = $this->getBuildDataClass();

        try {
            $this->reqData = new $buildClass($this->config, $data);
        } catch (PayException $e) {
            throw $e;
        }

        $this->reqData->setSign();

        $xml = DataParser::toXml($this->reqData->getData());
        $ret = $this->sendReq($xml);

        return $this->retData($ret);
    }
}
